package com.xm.limiter;

/**
 * 滑动窗口算法
 */
public class SlidingWindowLimiter02 implements Limiter {
    private final int limit; // 限流阈值
    private final long windowSize; // 时间窗口大小（毫秒）
    private final int[] window; // 窗口数组
    private long lastTime = System.currentTimeMillis();
    private int index = 0;

    /**
     * 滑动窗口算法：需要更平滑流量控制的场景（如API网关）
     * @param limit 限流阈值
     * @param windowSize 时间窗口大小（毫秒）
     * @param windowCount 窗口数组
     */
    public SlidingWindowLimiter02(int limit, long windowSize, int windowCount) {
        this.limit = limit;
        this.windowSize = windowSize;
        this.window = new int[windowCount];
    }

    @Override
    public synchronized boolean tryAcquire() {
        long now = System.currentTimeMillis();
        long elapsed = now - lastTime;
        int slideCount = (int) (elapsed / (windowSize / window.length));
        if (slideCount > 0) {
            for (int i = 0; i < slideCount; i++) {
                index = (index + 1) % window.length;
                window[index] = 0;
            }
            lastTime = now;
        }
        int total = 0;
        for (int count : window) {
            total += count;
        }
        if (total < limit) {
            window[index]++;
            return true;
        }
        return false;
    }
}